package com.ruoyi.hbsutils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.HttpUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.hbs.domain.ApiConfig;
import com.ruoyi.hbs.mapper.ApiConfigMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wl
 * @description: hbs工具请求工具类
 * @date 2025年11月05日11:39
 */
@Slf4j
@Component
public class HbsUtil {
    private static final String ITEMS_KEY = "items";
    private static final String MSG_KEY = "message";
    private static final String DATA_KEY = "data";
    private static final String CODE_KEY = "code";
    private static final String COUNT_KEY = "count";

    private static final String ERROR_MESSAGE_TEMPLATE = "对接[HBS]%s失败,错误原因:%s";
    @Autowired
    private ApiConfigMapper apiConfigMapper;


    /**
     * 业务get请求
     *
     * @param url
     * @param spaceName
     * @param params
     * @param bodyJson
     * @return
     * @throws Exception
     */
    public JSONObject getHBSService(String url, String spaceName, Map<String, Object> params, JSON bodyJson,String message) throws Exception {
        JSONObject jsonObject = null;
        try {
            jsonObject = MethodJsonObject(url, spaceName, Method.GET, params, bodyJson);
        } catch (Exception e) {
            log.error(String.format(ERROR_MESSAGE_TEMPLATE, message, e.getMessage()), e);
            throw new Exception(e.getMessage());
        }
        return jsonObject;
    }


    /**
     * JSONArray业务get请求
     *
     * @param url
     * @param params
     * @param bodyJson
     * @param message
     * @return
     * @throws Exception
     */
    public JSONArray getJSONArrayHBSService(String url, String spaceName, Map<String, Object> params, JSON bodyJson,String message) throws Exception {
        JSONArray jsonArray = null;
        try {
            jsonArray = MethodJSONArray(url, spaceName, Method.GET, params, bodyJson);
        } catch (Exception e) {
            log.error(String.format(ERROR_MESSAGE_TEMPLATE, message, e.getMessage()), e);
            throw new Exception(e.getMessage());
        }
        return jsonArray;
    }

    /**
     * 业务post请求
     *
     * @param url
     * @param spaceName
     * @param params
     * @param bodyJson
     * @return
     * @throws Exception
     */
    public R postHBSService(String url, String spaceName, Map<String, Object> params, JSON bodyJson,String message) throws Exception {
        JSONObject jsonObject = null;
        try {
            jsonObject = MethodJsonObject(url, spaceName, Method.POST, params, bodyJson);
        } catch (Exception e) {
            log.error(String.format(ERROR_MESSAGE_TEMPLATE, message, e.getMessage()), e);
            throw new Exception(e.getMessage());
        }
        return getBaseResp(message,jsonObject);
    }

    /**
     * 业务put请求
     *
     * @param url
     * @param spaceName
     * @param params
     * @param bodyJson
     * @return
     * @throws Exception
     */
    public R putHBSService(String url, String spaceName, Map<String, Object> params, JSON bodyJson,String message) throws Exception {
        JSONObject jsonObject = null;
        try {
            jsonObject = MethodJsonObject(url, spaceName, Method.PUT, params, bodyJson);
        } catch (Exception e) {
            log.error(String.format(ERROR_MESSAGE_TEMPLATE, message, e.getMessage()), e);
            throw new Exception(e.getMessage());
        }
        return getBaseResp(message,jsonObject);
    }


    /**
     * 业务JSONArray post请求
     *
     * @param url
     * @param spaceName
     * @param params
     * @param bodyJson
     * @return
     * @throws Exception
     */
    public JSONArray postJSONArrayHBSService(String url, String spaceName, Map<String, Object> params, JSON bodyJson,String message) throws Exception {
        JSONArray jsonArray = null;
        try {
            jsonArray = MethodJSONArray(url, spaceName, Method.POST, params, bodyJson);

        } catch (Exception e) {
            log.error(String.format(ERROR_MESSAGE_TEMPLATE, message, e.getMessage()), e);
            throw new Exception(e.getMessage());
        }
        return jsonArray;
    }

    /**
     * 请求方法
     *
     * @param url
     * @param spaceName
     * @param methodEnum
     * @param params
     * @param bodyJson
     * @return
     * @throws Exception
     */
    private JSONArray MethodJSONArray(String url, String spaceName, Method methodEnum, Map<String, Object> params, JSON bodyJson) throws Exception {
        JSONArray jsonArray = null;
        ApiConfig apiConfig = apiConfigMapper.selectOne(new LambdaQueryWrapper<ApiConfig>().eq(ApiConfig::getSpaceName, spaceName));
        if (ObjectUtil.isNull(apiConfig)) {
            throw new Exception("获取配置信息异常" + spaceName);
        }
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Open-Authorization", apiConfig.getApiKey());
//        headers.put("'X-Huoban-Return-Alias-Space-Id", apiConfig.getSpaceId());
        if (Method.GET.equals(methodEnum)) {
            jsonArray = getJSONArray(apiConfig.getApiUrl() + url, params, headers);
        } else {
            jsonArray = postJSONArray(apiConfig.getApiUrl() + url, params, bodyJson, headers);
        }
        return jsonArray;
    }

    /**
     * 请求方法
     *
     * @param url
     * @param spaceName
     * @param methodEnum
     * @param params
     * @param bodyJson
     * @return
     * @throws Exception
     */
    private JSONObject MethodJsonObject(String url, String spaceName, Method methodEnum, Map<String, Object> params, JSON bodyJson) throws Exception {
        ApiConfig apiConfig = apiConfigMapper.selectOne(new LambdaQueryWrapper<ApiConfig>().eq(ApiConfig::getSpaceName, spaceName));
        if (ObjectUtil.isNull(apiConfig)) {
            throw new Exception("获取配置信息异常" + spaceName);
        }
        JSONObject jsonObject = null;
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Open-Authorization", apiConfig.getApiKey());
//        headers.put("'X-Huoban-Return-Alias-Space-Id", apiConfig.getSpaceId());
        if (Method.GET.equals(methodEnum)) {
            jsonObject = get(apiConfig.getApiUrl() + url, params, headers);
        } else if(Method.POST.equals(methodEnum)){
            jsonObject = post(apiConfig.getApiUrl() + url, params, bodyJson, headers);
        }else if(Method.PUT.equals(methodEnum)){
            jsonObject = put(apiConfig.getApiUrl() + url, params, bodyJson, headers);
        }
        return jsonObject;
    }

    /**
     * post请求
     *
     * @param url      请求地址
     * @param params   参数
     * @param bodyJson 请求体内容
     * @return 返回内容
     * @throws Exception 错误
     */
    public JSONObject post(String url, Map<String, Object> params, JSON bodyJson, HashMap<String, String> headers) throws Exception {
        String body = JSONUtil.toJsonStr(bodyJson);
        try (Response post = HttpUtil.post(url, params, StringUtils.isEmpty(body) ? JSONUtil.toJsonStr(new Object()) : body, headers)) {
            if (post.code() != 200) {
                log.error("请求[HBS]失败！响应状态码{},响应参数{}", post.code(), post.message());
                throw new Exception("请求[HBS]失败！响应状态码" + post.code() + "响应参数" + post.message());
            }
            return JSONUtil.parseObj(post.body().string());
        }
    }

    /**
     * put
     *
     * @param url      请求地址
     * @param params   参数
     * @param bodyJson 请求体内容
     * @return 返回内容
     * @throws Exception 错误
     */
    public JSONObject put(String url, Map<String, Object> params, JSON bodyJson, HashMap<String, String> headers) throws Exception {
        String body = JSONUtil.toJsonStr(bodyJson);
        try (Response post = HttpUtil.put(url, params, StringUtils.isEmpty(body) ? JSONUtil.toJsonStr(new Object()) : body, headers)) {
            if (post.code() != 200) {
                log.error("请求[HBS]失败！响应状态码{},响应参数{}", post.code(), post.message());
                throw new Exception("请求[HBS]失败！响应状态码" + post.code() + "响应参数" + post.message());
            }
            return JSONUtil.parseObj(post.body().string());
        }
    }

    /**
     * JSONArraypost请求
     *
     * @param url      请求地址
     * @param params   参数
     * @param bodyJson 请求体内容
     * @return 返回内容
     * @throws Exception 错误
     */
    public JSONArray postJSONArray(String url, Map<String, Object> params, JSON bodyJson, HashMap<String, String> headers) throws Exception {
        String body = JSONUtil.toJsonStr(bodyJson);
        try (Response post = HttpUtil.post(url, params, StringUtils.isEmpty(body) ? JSONUtil.toJsonStr(new Object()) : body, headers)) {
            if (post.code() != 200) {
                log.error("请求[HBS]失败！响应状态码{},响应参数{}", post.code(), post.message());
                throw new Exception("请求[HBS]失败！响应状态码" + post.code() + "响应参数" + post.message());
            }
            return JSONUtil.parseArray(post.body().string());
        }
    }


    /**
     * get请求
     *
     * @param url    请求地址
     * @param params 参数
     * @return 返回内容
     * @throws Exception 错误
     */
    public JSONObject get(String url, Map<String, Object> params, HashMap<String, String> headers) throws Exception {
        try (Response post = HttpUtil.get(url, params, headers)) {
            if (post.code() != 200) {
                log.error("请求[HBS]失败！响应状态码{},响应参数{}", post.code(), post.message());
                throw new Exception("请求[HBS]失败！响应状态码" + post.code() + "响应参数" + post.message());
            }
            return JSONUtil.parseObj(post.body().string());
        }
    }

    /**
     * JSONArrayget请求
     *
     * @param url    请求地址
     * @param params 参数
     * @return 返回内容
     * @throws Exception 错误
     */
    public JSONArray getJSONArray(String url, Map<String, Object> params, HashMap<String, String> headers) throws Exception {
        try (Response get = HttpUtil.get(url, params, headers)) {
            if (get.code() != 200) {
                log.error("请求[HBS]失败！响应状态码{},响应参数{}", get.code(), get.message());
                throw new Exception("请求[HBS]失败！响应状态码" + get.code() + "响应参数" + get.message());
            }
            return JSONUtil.parseArray(get.body().string());
        }
    }
    /**
     * 公共方法抽取
     *
     * @param message
     * @param postResponse
     * @return
     */
    @NotNull
    private R getBaseResp(String message, JSONObject postResponse) throws Exception {
        if (postResponse == null) {
            log.error(String.format(ERROR_MESSAGE_TEMPLATE, message, "响应为空"));
            throw new  Exception(String.format(ERROR_MESSAGE_TEMPLATE, message, "响应为空"));
        }
        Object code = postResponse.get(CODE_KEY);
        Object msg = postResponse.get(MSG_KEY);
        Object data = postResponse.get(DATA_KEY);
        Object items = postResponse.get(ITEMS_KEY);
        Long count = postResponse.getLong(COUNT_KEY);
        if (!ObjectUtil.equal(code, 0)) {
            if (ObjectUtil.isNotEmpty(msg)) {
                log.error(String.format(ERROR_MESSAGE_TEMPLATE, message, "响应状态码" + code + " 响应信息:" + msg));
                throw new  Exception(String.format(ERROR_MESSAGE_TEMPLATE, message, "响应状态码：" + code + "响应信息:" + msg));
            }
        }
        if (items != null) {
            return R.ok(items);
        } else if (data != null) {
            return R.ok(data);
        }
        return R.ok(postResponse);
    }

}
